﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Genuilder.Extensibility
{
	public class TaskQueue
	{
		public class TaskKey
		{
			public string Key
			{
				get;
				set;
			}
			public object Owner
			{
				get;
				set;
			}
			public override bool Equals(object obj)
			{
				TaskKey item = obj as TaskKey;
				if(item == null)
					return false;
				return item.Key.Equals(Key) && item.Owner.Equals(Owner);
			}
			public override int GetHashCode()
			{
				return Owner.GetHashCode() ^ Key.GetHashCode();
			}
		}

		class Task
		{
			public TaskKey Key
			{
				get;
				set;
			}
			public Action Action
			{
				get;
				set;
			}
		}

		Dictionary<TaskKey, Task> _TasksRegistry = new Dictionary<TaskKey, Task>();
		Queue<Task> _Actions = new Queue<Task>();

		public TaskKey Enqueue(Action action)
		{
			return Enqueue(new object(), "", action);
		}





		public TaskKey Enqueue(object owner, string key, Action action)
		{
			var keyContext = CreateKey(owner, key);
			return Enqueue(keyContext, action);
		}

		private TaskKey Enqueue(TaskKey keyContext, Action action)
		{
			Task task;
			if(_TasksRegistry.TryGetValue(keyContext, out task))
			{
				task.Action = action;
			}
			else
			{
				task = new Task()
				{
					Action = action,
					Key = keyContext
				};
				_TasksRegistry.Add(keyContext, task);
				_Actions.Enqueue(task);
			}
			return keyContext;
		}

		private TaskKey CreateKey(object owner, string key)
		{
			return new TaskKey()
			{
				Owner = owner,
				Key = key
			};
		}

		public void Run()
		{
			while(_Actions.Count > 0)
			{
				var action = _Actions.Dequeue();
				_TasksRegistry.Remove(action.Key);
				action.Action();
			}
		}
	}
}
